package test.br.com.lh.urabuilder.business
{
	import br.com.lh.urabuilder.business.ArrowManager;
	import br.com.lh.urabuilder.business.ArrowManagerImpl;
	import br.com.lh.urabuilder.model.UraModelLocator;
	import br.com.lh.urabuilder.util.pointchooser.TwoComponentPointChooser;
	import br.com.lh.urabuilder.view.ActionComponent;
	import br.com.lh.urabuilder.view.arrow.ArrowContainer;
	
	import flash.events.Event;
	import flash.geom.Point;
	
	import flexunit.framework.TestCase;
	import flexunit.framework.TestSuite;
	
	import mx.containers.Canvas;

	public class ArrowManagerImplTest extends TestCase
	{

		private var canvas:Canvas = new Canvas();
		private var arrowManager:ArrowManager;

		public function ArrowManagerImplTest(methodName:String=null){
			super(methodName);
		}

		public static function suite():TestSuite{
			var ts:TestSuite = new TestSuite();
			ts.addTest(new ArrowManagerImplTest("shouldIncreaseArrowCountAndAddToCanvas"));
			ts.addTest(new ArrowManagerImplTest("shouldMoveWithStartComponent"));
			ts.addTest(new ArrowManagerImplTest("shouldMoveWithEndComponent"));
			ts.addTest(new ArrowManagerImplTest("bindStartThenBindEndComponent"));
			ts.addTest(new ArrowManagerImplTest("shouldRemoveFromScreenAndComponentsList"));
			ts.addTest(new ArrowManagerImplTest("shouldUnbindComponentsAfterRemoval"));
			ts.addTest(new ArrowManagerImplTest("shouldClearArraysOnNewUra"));
			return ts;
		}

		public function shouldIncreaseArrowCountAndAddToCanvas():void{
			UraModelLocator.modelLocator = null;
			var canvas:Canvas = new Canvas();
			UraModelLocator.getInstance(canvas);
			var arrowManager:ArrowManager = new ArrowManagerImpl(canvas);
			var startCount:int = arrowManager.arrowCount;
			var startPoint:Point = new Point(10,10);
			var endPoint:Point = new Point(20,40);
			var arrowContainer:ArrowContainer = arrowManager.insertArrow(startPoint,endPoint);
			assertEquals(1,arrowManager.arrowCount);
			assertEquals(1,canvas.getChildren().length);
			assertTrue(canvas.contains(arrowContainer));
		}

		public function shouldMoveWithStartComponent():void{
			canvas = new Canvas();
			arrowManager = new ArrowManagerImpl(canvas);
			var arrowContainer:ArrowContainer = baseArrowWithNoComponentsBound();
			var startComponent:ActionComponent = new ActionComponent();
			canvas.addChild(startComponent);
			arrowManager.bindStartComponent(arrowContainer,startComponent);
			startComponent.buildPoints();
			assertTrue(startComponent.outArrows.getItemIndex(arrowContainer) != -1);
			startComponent.x = 200;
			var changedStartPoint:Point = arrowContainer.startPoint;
			assertTrue(changedStartPoint.x != 0);
			startComponent.y = 200;
			changedStartPoint = arrowContainer.startPoint;
			assertTrue(changedStartPoint.y != 0);
		}
		public function bindStartThenBindEndComponent():void{
			canvas = new Canvas();
			arrowManager = new ArrowManagerImpl(canvas);
			var arrowContainer:ArrowContainer = baseArrowWithNoComponentsBound();
			var startComponent:ActionComponent = new ActionComponent();
			canvas.addChild(startComponent);
			startComponent.buildPoints();
			arrowManager.bindStartComponent(arrowContainer,startComponent);
			var endComponent:ActionComponent = new ActionComponent();
			canvas.addChild(endComponent);
			endComponent.image.executeBindings();
			endComponent.buildPoints();
			arrowManager.bindEndComponent(arrowContainer,endComponent);
			endComponent.x = 200;
			assertTrue(arrowContainer.endPoint.x != 10);
		}


		public function shouldMoveWithEndComponent():void{
			canvas = new Canvas();
			arrowManager = new ArrowManagerImpl(canvas);
			var arrowContainer:ArrowContainer = baseArrowWithNoComponentsBound();
			var endComponent:ActionComponent = new ActionComponent();
			canvas.addChild(endComponent);
			endComponent.buildPoints();
			arrowManager.bindEndComponent(arrowContainer,endComponent);
			assertTrue(endComponent.entryArrows.getItemIndex(arrowContainer) != -1);
			endComponent.x = 200;
			var changedStartPoint:Point = arrowContainer.startPoint;
			assertTrue(changedStartPoint.x != 10);
			endComponent.y = 200;
			changedStartPoint = arrowContainer.startPoint;
			assertTrue(changedStartPoint.y != 10);
		}
		
	
		

		public function shouldRemoveFromScreenAndComponentsList():void{
			var startComponent:ActionComponent = new ActionComponent();
			var endComponent:ActionComponent = new ActionComponent();
			var arrowContainer:ArrowContainer = baseArrowWithTwoComponentsBound(startComponent,endComponent);
			arrowManager.removeArrow(arrowContainer);
			assertFalse(canvas.contains(arrowContainer));
			assertEquals(startComponent.outArrows.length,0);
			assertEquals(endComponent.entryArrows.length,0);
		}
		public function shouldUnbindComponentsAfterRemoval():void{
			var startComponent:ActionComponent = new ActionComponent();
			var endComponent:ActionComponent = new ActionComponent();
			var arrowContainer:ArrowContainer = baseArrowWithTwoComponentsBound(startComponent,endComponent);
			arrowManager.removeArrow(arrowContainer);
			startComponent.x =200;
			assertEquals(0,arrowContainer.startPoint.x);
			startComponent.y = 200;
			assertEquals(0,arrowContainer.startPoint.y);
			endComponent.x = 200;
			assertEquals(10,arrowContainer.endPoint.x);
			endComponent.y = 200;
			assertEquals(10,arrowContainer.endPoint.y);
		}

		public function shouldClearArraysOnNewUra():void{
			canvas = new Canvas();
			arrowManager = new ArrowManagerImpl(canvas);
			var arrowContainer:ArrowContainer =baseArrowWithNoComponentsBound();
			assertEquals(1,arrowManager.arrowCount);
			arrowManager.clearUra();
			assertEquals(0,arrowManager.arrowCount);
		}
		
		

		private function baseArrowWithTwoComponentsBound(startComponent:ActionComponent,endComponent:ActionComponent):ArrowContainer{
			canvas = new Canvas();
			arrowManager = new ArrowManagerImpl(canvas);
			var arrowContainer:ArrowContainer = baseArrowWithNoComponentsBound();
			canvas.addChild(startComponent);
			startComponent.image.executeBindings();
			startComponent.buildPoints();
			canvas.addChild(endComponent);
			endComponent.image.executeBindings();
			endComponent.buildPoints();
			arrowManager.bindStartComponent(arrowContainer,startComponent);
			arrowManager.bindEndComponent(arrowContainer,endComponent);
			return arrowContainer;
		}



		private function baseArrowWithNoComponentsBound():ArrowContainer{
			UraModelLocator.modelLocator = null;
			UraModelLocator.getInstance(canvas);
			var startCount:int = arrowManager.arrowCount;
			var startPoint:Point = new Point(0,0);
			var endPoint:Point = new Point(10,10);
			return arrowManager.insertArrow(startPoint,endPoint);
		}



	}
}
